package org.dallasrowing.logbook.ui.controller;

import java.util.List;

import org.dallasrowing.logbook.Constants;
import org.dallasrowing.logbook.event.ChangeListener;
import org.dallasrowing.logbook.ui.view.LogBookWindow;
import org.dallasrowing.model.LogBookEntry;
import org.dallasrowing.model.dao.BoatsDAO;
import org.dallasrowing.model.dao.DAOException;
import org.dallasrowing.model.dao.DamagesDAO;
import org.dallasrowing.model.dao.LogBookDAO;
import org.dallasrowing.model.dao.RowersDAO;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;

public class LogBookUiControllerImpl implements LogBookUiController {
	
	private LogBookWindow mainWindow;
	private BoatsDAO boatsDao;
	private RowersDAO rowersDAO;
	private LogBookDAO logBookDAO;
	private DamagesDAO damagesDAO;

	public LogBookUiControllerImpl(LogBookWindow mainWindow, BoatsDAO boatsDao, RowersDAO rowersDAO, LogBookDAO logBookDAO, DamagesDAO damagesDAO) {
		this.boatsDao = boatsDao;
		this.rowersDAO = rowersDAO;
		this.logBookDAO = logBookDAO;
		this.mainWindow = mainWindow;
		this.damagesDAO = damagesDAO;
	}

	public void create() {
		registerListeners();
		updateWindowData();
		mainWindow.openWindow();
	}

	private void registerListeners() {
		mainWindow.setCreateNewButtonAction(new Runnable() {
			public void run() {
				createButtonClicked();
			}
		});

		mainWindow.setSignOutButtonAction(new Runnable() {
			public void run() {
				signOutButtonClicked();
			}
		});
		
		mainWindow.setNewDamageButtonAction(new Runnable() {
			public void run() {
				newDamageButtonClicked();
			}
		});

		mainWindow.setOpenReportsButtonAction(new Runnable() {
			public void run() {
				openReportsButtonClicked();
			}
		});
		
		mainWindow.setTableScrollDownListener(new Listener() {
		
			public void handleEvent(Event event) {
				int index = event.index;
				int page = index / Constants.PAGE_SIZE;
				int start = page * Constants.PAGE_SIZE;
				addLogBookEntries(start);
			}
		});
		
		mainWindow.setAdminButtonAction(new Runnable() {
			public void run() {
				openAdminWindow();
			}
		});
		
		logBookDAO.registerChangeListener(new ChangeListener() {
			public void hasChanged() {
				updateWindowData();
			}
		});
	}

	protected void openAdminWindow() {
		AdminWindowController controller = new AdminWindowControllerImpl(mainWindow, rowersDAO, boatsDao);
		controller.newWindow(mainWindow.createAdminWindow());
		controller.openWindow();
	}

	protected void addLogBookEntries(int index) {
		try {
			List<LogBookEntry> result = logBookDAO.getEntriesSortByDate(index, Constants.PAGE_SIZE);
			mainWindow.addAdditionalEntries(index, result);
		} catch (DAOException e) {
			mainWindow.showError(e);
		}
	}

	protected void openReportsButtonClicked() {
		ReportsController controller = new ReportsControllerImpl(mainWindow);
		controller.openReportsWindow(mainWindow.createReportsWindow());
	}

	protected void signOutButtonClicked() {
		SignOutWindowController controller = new SignOutWindowControllerImpl(mainWindow, logBookDAO);
		controller.newSignOutWindow(mainWindow.openSignOutWindow());
		controller.openSignOutWindow(this);
	}

	protected void createButtonClicked() {
		NewLogEntryController controller = new NewLogEntryControllerImpl(mainWindow, boatsDao, rowersDAO, logBookDAO);
		controller.newLogEntryWindow(mainWindow.openNewEntryWindow());
		controller.openNewEntryWindow(this);
	}

	protected void newDamageButtonClicked() {
		ReportNewDamageController controller = new ReportNewDamageControllerImpl(mainWindow, boatsDao, damagesDAO);
		controller.newReportNewDamageWindow(mainWindow.openReportNewDamageWindow());
		controller.openReportNewDamageWindow();
	}
	
	private void updateLogBookEntries() {
		try {
			List<LogBookEntry> logBookEntries = logBookDAO.getEntriesSortByDate(0, Constants.PAGE_SIZE);
			int count = logBookDAO.getEntriesCount();
			mainWindow.initialFillTableEntries(count, logBookEntries);
		} catch (DAOException e) {
			mainWindow.showError(e);
		}
	}

	void updateWindowData() {
		updateLogBookEntries();
	}

}
